package pe.com.fondam.sgp.web.controller.principal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import pe.com.fondam.sgp.core.bean.ProgramaBean2;
import pe.com.fondam.sgp.core.domain.CostoActividad;
import pe.com.fondam.sgp.core.domain.CronogramaCostoActividad;
import pe.com.fondam.sgp.core.domain.CronogramaMetaPorActividad;
import pe.com.fondam.sgp.core.domain.CronogramaMetaPorResultado;
import pe.com.fondam.sgp.core.domain.DatoPlanOperativo;
import pe.com.fondam.sgp.core.domain.DatoProyecto;
import pe.com.fondam.sgp.core.domain.DetalleEstadoCabecera;
import pe.com.fondam.sgp.core.domain.MetaPorActividad;
import pe.com.fondam.sgp.core.domain.Programa;
import pe.com.fondam.sgp.core.domain.TablaEspecifica;
import pe.com.fondam.sgp.core.domain.TipoPeriodo;
import pe.com.fondam.sgp.core.form.planOperativo.ActividadForm;
import pe.com.fondam.sgp.core.form.planOperativo.PlanOperativoForm;
import pe.com.fondam.sgp.core.form.planOperativo.ResultadoForm;
import pe.com.fondam.sgp.core.service.CostoActividadService;
import pe.com.fondam.sgp.core.service.CrearProgramaService;
import pe.com.fondam.sgp.core.service.CronogramaCostoActividadService;
import pe.com.fondam.sgp.core.service.CronogramaMetaPorActividadService;
import pe.com.fondam.sgp.core.service.CronogramaMetaPorResultadoService;
import pe.com.fondam.sgp.core.service.DatoProyectoService;
import pe.com.fondam.sgp.core.service.DetalleEstadoCabeceraService;
import pe.com.fondam.sgp.core.service.EvaluarService;
import pe.com.fondam.sgp.core.service.InstalarComiteTecnicoService;
import pe.com.fondam.sgp.core.service.MarcoLogicoService;
import pe.com.fondam.sgp.core.service.MetaPorActividadService;
import pe.com.fondam.sgp.core.service.PlanOperativoService;
import pe.com.fondam.sgp.core.service.TablaEspecificaService;
import pe.com.fondam.sgp.core.service.TablaTemporalService;
import pe.com.fondam.sgp.core.service.TipoPeriodoService;
import pe.com.fondam.sgp.core.service.UtilService;
import pe.com.fondam.sgp.core.util.UtilList;
import pe.com.fondam.sgp.core.util.UtilValidate;
import pe.com.fondam.sgp.web.session.UserSession;

@Controller()
public class EvalPlanOperativoController {

	protected final Log logger = LogFactory
			.getLog(EvalPlanOperativoController.class);

	@Resource
	DetalleEstadoCabeceraService detalleEstadoCabeceraService;

	@Resource
	TablaEspecificaService tablaEspecificaService;

	@Resource
	TablaTemporalService tablaTemporalService;

	@Resource
	CrearProgramaService crearProgramaService;

	@Resource
	EvaluarService evaluarService;

	@Resource
	MarcoLogicoService marcoLogicoService;

	@Resource
	InstalarComiteTecnicoService instalarComiteTecnicoService;

	@Resource
	PlanOperativoService planOperativoService;

	@Resource
	UtilService utilService;

	@Resource
	DatoProyectoService datoProyectoService;

	@Resource
	TipoPeriodoService tipoPeriodoService;

	@Resource
	CronogramaMetaPorResultadoService cronogramaMetaPorResultadoService;

	@Resource
	MetaPorActividadService metaPorActividadService;

	@Resource
	CronogramaMetaPorActividadService cronogramaMetaPorActividadService;

	@Resource
	CostoActividadService costoActividadService;

	@Resource
	CronogramaCostoActividadService cronogramaCostoActividadService;

	List<TipoPeriodo> listTipoPeriodos;
	List<TablaEspecifica> listTipoCuentas;
	List<TablaEspecifica> listModalidadFinanciera;
	List<Programa> listaPrograma = null;

	void cargaCombos() {
		listTipoPeriodos = crearProgramaService.listTipoPeriodos();
		listTipoCuentas = tablaEspecificaService
				.listTablaEspecificaByTablaGeneralId(1);
		listModalidadFinanciera = tablaEspecificaService
				.listTablaEspecificaByTablaGeneralId(2);
	}

	@RequestMapping(value = "/principal/showEvaluarPlanOperativo.jspx")
	public ModelAndView showEvaluarPlanOperativo(HttpServletRequest request) {

		listaPrograma = crearProgramaService.listProgramas();

		request.getSession().setAttribute("listaProgramaAndProyecto",
				listaPrograma);
		cargaCombos();
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("listTipoPeriodos", listTipoPeriodos);
		model.put("listTipoCuentas", listTipoCuentas);
		model.put("listModalidadFinanciera", listModalidadFinanciera);
		model.put("funcionalidadSelect", "showEvaluarPlanOperativo.jspx");
		model.put("cargarProyecto", 0);

		return new ModelAndView("mostrarEvaluarPlanOperativo", model);
	}

	@RequestMapping(value = "/principal/actionBuscarEvaluarPlanOperativo")
	public ModelAndView actionBuscarEvaluarPlanOperativo(
			HttpServletRequest request) {
		request.getSession().removeAttribute("listaProgramaAndProyecto");

		Programa programa = new Programa();
		Integer idTipoCuentas = Integer.parseInt(request.getParameter(
				"idTipoCuentas").toString());
		Integer idModalidadFinanciera = Integer.parseInt(request.getParameter(
				"idModalidadFinanciera").toString());
		Integer idTipoPeriodos = Integer.parseInt(request.getParameter(
				"idTipoPeriodos").toString());
		Integer nombre = Integer.parseInt(request.getParameter("idFiltro"));
		String nombrePrograma = request.getParameter("buscarNombre");
		Integer todosProgramas = Integer.parseInt(request
				.getParameter("idFiltro"));
		int tipoPeriodo = 100;
		int tipoCuenta = 101;
		int Modalidad = 102;

		if (idTipoPeriodos != 0) {
			TipoPeriodo tipPeriodo = new TipoPeriodo();
			tipPeriodo.setTipoPeriodoID(idTipoPeriodos);
			programa.setTipoPeriodo(tipPeriodo);
			listaPrograma = instalarComiteTecnicoService.findProgramaByFiltro(
					programa, tipoPeriodo);
		} else if (idTipoCuentas != 0) {
			programa.setFkIdtablaespTipoCuenta(idTipoCuentas);
			listaPrograma = instalarComiteTecnicoService.findProgramaByFiltro(
					programa, tipoCuenta);
		} else if (idModalidadFinanciera != 0) {
			programa.setFkIdtablaespModalidadFinancia(idModalidadFinanciera);
			listaPrograma = instalarComiteTecnicoService.findProgramaByFiltro(
					programa, Modalidad);
		} else if (nombre == 103) {
			programa.setNombrePrograma(nombrePrograma);
			listaPrograma = instalarComiteTecnicoService.findProgramaByFiltro(
					programa, nombre);
		} else if (todosProgramas == 104) {
			listaPrograma = crearProgramaService.listProgramas();
		}
		request.getSession().setAttribute("listaProgramaAndProyecto",
				listaPrograma);
		cargaCombos();
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("listTipoPeriodos", listTipoPeriodos);
		model.put("listTipoCuentas", listTipoCuentas);
		model.put("listModalidadFinanciera", listModalidadFinanciera);
		model.put("cargarProyecto", 0);
		return new ModelAndView("mostrarEvaluarPlanOperativo", model);
	}

	@RequestMapping(value = "/principal/actionCargarProyectosEvaluarPlanOperativo")
	public ModelAndView actionCargarProyectosEvaluarPlanOperativo(
			HttpServletRequest request) {
		if (request.getSession().getAttribute("listaDatoProyecto") != null) {
			request.getSession().removeAttribute("listaDatoProyecto");
		}
		Integer idPrograma = Integer.parseInt(request
				.getParameter("idPrograma"));
		List<DatoProyecto> listDatoProyecto =llenaListDatoProyectoCompleto( evaluarService.findDatoProyectoByProgramaID(idPrograma));

		if (listDatoProyecto != null && listDatoProyecto.size() != 0) {
			request.getSession().setAttribute("listDatoProyecto",
					listDatoProyecto);
		} else {
			request.getSession().setAttribute("listDatoProyecto", null);

		}
		request.getSession().setAttribute("listTipoPeriodos", listTipoPeriodos);
		request.getSession().setAttribute("listTipoCuentas", listTipoCuentas);
		request.getSession().setAttribute("listModalidadFinanciera",
				listModalidadFinanciera);

		ProgramaBean2 programaBean = llenarProgramaBean(crearProgramaService
				.findProgramaById(idPrograma));

		Map<String, Object> model = new HashMap<String, Object>();
		// model.put("mensajeEvaluador",mensaje);
		model.put("cargarProyecto", 1);
		model.put("programa", programaBean);

		return new ModelAndView("mostrarEvaluarPlanOperativo", model);
	}

	@RequestMapping(value = "/principal/actionShowEvaluarPlanOperativo")
	public ModelAndView actionShowEvaluarPlanOperativo(
			@RequestParam(required = false, value = "mensaje") String mensaje,
			HttpServletRequest request) {

		Map<String, Object> model = new HashMap<String, Object>();
		Integer datoProyectoID = Integer.parseInt(request
				.getParameter("datoProyectoID"));
		DatoProyecto datoProyecto = datoProyectoService
				.findDatoProyectoById(datoProyectoID);
		PlanOperativoForm planOperativo = null;
		if (UtilValidate.isNotEmpty(datoProyectoID)) {
			planOperativo = llenaPlanOprativoTotal(planOperativoService
					.obtenerPlanOperativoByProyectoID(datoProyectoID));

		}
		// MarcoLogico marcoLogico =
		// marcoLogicoService.findMarcoLogicoByDatoProyectoID(datoProyectoID);
		/*
		 * try { request.getSession().setAttribute("listaResultado",
		 * planOperativo.getListResultadoForm());
		 * request.getSession().setAttribute("marcoLogico", marcoLogico);
		 * request.getSession().setAttribute("planOperativo", planOperativo);
		 * 
		 * } catch (Exception e) { // TODO: handle exception }
		 */

		ProgramaBean2 programaBean = llenarProgramaBean(datoProyecto
				.getPrograma());
		List<DetalleEstadoCabecera> listDetalleEstadoCabecera = detalleEstadoCabeceraService
				.findDetalleEstadoCabecerabyPrefijoEstadoCabeceraPrefijo("estplo");
		List<DetalleEstadoCabecera> listDetalleEstadoCabeceraTemp = new ArrayList<DetalleEstadoCabecera>();
		for (DetalleEstadoCabecera detalleEstadoCabecera : listDetalleEstadoCabecera) {
			if ((detalleEstadoCabecera.getPrefijoEstado().equals("peval"))
					|| (detalleEstadoCabecera.getPrefijoEstado().equals("apro"))
					|| (detalleEstadoCabecera.getPrefijoEstado()
							.equals("recha"))
					|| (detalleEstadoCabecera.getPrefijoEstado().equals("elab"))) {
				listDetalleEstadoCabeceraTemp.add(detalleEstadoCabecera);
			}
		}
UserSession userSession= (UserSession) request.getSession().getAttribute("USER_SESSION");

		model.put("userSession", userSession);
		model.put("datoProyectoID", datoProyectoID);
		model.put("listaEstadoCabecera", listDetalleEstadoCabeceraTemp);
		model.put("cargarProyecto", 2);
		model.put("proyectoBean", datoProyecto);
		model.put("planOperativo", planOperativo);
		model.put("programa", programaBean);
		model.put("mensaje", mensaje);
		return new ModelAndView("mostrarEvaluarPlanOperativo", model);
	}

	@RequestMapping(value = "/principal/actionGrabarEvaluacionPlanOperativo", method = RequestMethod.POST)
	public String actionGrabarEvaluacionPlanOperativo(
			@RequestParam(required = true, value = "estado") Integer estadoId,
			@RequestParam(required = true, value = "datoPlanOperativoId") Integer datoPlanOperativoId,
			HttpServletRequest request) {
		
	/*	if (request.getSession().getAttribute("listaProgramaAndProyecto") != null) {
			request.getSession().removeAttribute("listaProgramaAndProyecto");
		}
		Integer datoPlanOperativoID = Integer.parseInt(request
				.getParameter("datoPlanOperativoID"));
		Integer estadoID = Integer.parseInt(request.getParameter("estadoID"));
*/
		DatoPlanOperativo planOperativo = planOperativoService
				.findPlanOperativoByID(datoPlanOperativoId);
		if (planOperativo != null) {
			planOperativo.setFkIdDetalleEstadoCabEstadoPlanOper(estadoId);
			planOperativoService.updatePlanOperativo(planOperativo);
		}
String mensaje = "Se cambio el estado del Plan Operativo satisfactoriamente.";
		/*listaPrograma = crearProgramaService.listProgramas();
		request.getSession().setAttribute("listaProgramaAndProyecto",
				listaPrograma);
		//cargaCombos();
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("listTipoPeriodos", listTipoPeriodos);
		model.put("listTipoCuentas", listTipoCuentas);
		model.put("listModalidadFinanciera", listModalidadFinanciera);
		model.put("cargarProyecto", 0);
*/
		//return new ModelAndView("mostrarEvaluarPlanOperativo", model);
		return "redirect:actionShowEvaluarPlanOperativo.jspx?datoProyectoID="
				+ planOperativo.getDatoProyecto().getDatoProyectoID()+"&mensaje="+mensaje;
	}

	// ****************** listas *******************************
	private List<DatoProyecto> llenaListDatoProyectoCompleto(
			List<DatoProyecto> listDatoProyecto) {

for (DatoProyecto datoProyecto : listDatoProyecto) {
	datoProyecto.setDescripcionEstadoProyecto(detalleEstadoCabeceraService.findDetalleEstadoCabeceraById(datoProyecto.getFkIddetallestadocabEstproy()).getDescripEstado());
}
		return listDatoProyecto;
	}
	
	private ProgramaBean2 llenarProgramaBean(Programa programa) {
		ProgramaBean2 programaBean = new ProgramaBean2();

		programaBean.setDuracionPrograma(programa.getDuracionPrograma());
		programaBean.setFkIdtablaespModalidadFinancia(programa
				.getFkIdtablaespModalidadFinancia());
		programaBean.setFkIdtablaespTipoCuenta(programa
				.getFkIdtablaespTipoCuenta());
		programaBean.setModalidadFinancia(tablaEspecificaService
				.findTablaEspecificaById(
						programa.getFkIdtablaespModalidadFinancia())
				.getDescripcionCabecera());
		programaBean.setNombrePrograma(programa.getNombrePrograma());
		programaBean.setNombreTipoPeriodo(tipoPeriodoService
				.findTipoPeriodoById(
						programa.getTipoPeriodo().getTipoPeriodoID())
				.getDescripPeriodo());

		return programaBean;
	}

	@SuppressWarnings("unchecked")
	private PlanOperativoForm llenaPlanOprativoTotal(
			PlanOperativoForm planOperativoForm) {

		if (planOperativoForm != null) {
			for (ResultadoForm resultadoForm : planOperativoForm
					.getListResultadoForm()) {
				List<ActividadForm> listActividadForm = planOperativoService
						.obtenerListaActividadByResultadoID(resultadoForm
								.getResultadoID());
				resultadoForm
						.setListCronogramaMetaForm(planOperativoService
								.setDataListCronogramaMetaForm((List<CronogramaMetaPorResultado>) UtilList.orderAscList(
										cronogramaMetaPorResultadoService
												.findCronogramaMetaPorResultadoByResultadoID(resultadoForm
														.getResultadoID()),
										"periodo")));
				if (listActividadForm != null) {
					resultadoForm
							.setListActividadForm(llenaListActividadCompleto((List<ActividadForm>) UtilList
									.orderAscList(listActividadForm,
											"codigoActividad")));
				}
			}
		}
		return planOperativoForm;
	}

	private List<ActividadForm> llenaListActividadCompleto(
			List<ActividadForm> listaActividadForm) {
		if (listaActividadForm != null) {
			for (ActividadForm actividadForm : listaActividadForm) {
				actividadForm
						.setListMetaPorActividad(llenaMetaPorActividad(metaPorActividadService
								.findMetaPorActividadXActividadId(actividadForm
										.getActividadID())));
				actividadForm
						.setListCostoActividad(llenaCostoActividad(costoActividadService
								.findCostoActividadByActividadID(actividadForm
										.getActividadID())));
			}
		}
		return listaActividadForm;
	}

	@SuppressWarnings("unchecked")
	private List<CostoActividad> llenaCostoActividad(
			List<CostoActividad> listCostoActividad) {

		if (listCostoActividad != null) {
			for (CostoActividad costoActividad : listCostoActividad) {
				costoActividad.setDescripcionTipoMoneda(tablaEspecificaService
						.findTablaEspecificaById(
								costoActividad.getFkIdtablaespTipoMoneda())
						.getDescripcionCabecera());
				costoActividad
						.setDescripcionUnidadMedida(tablaEspecificaService
								.findTablaEspecificaById(
										costoActividad
												.getFkIdtablaespUnidadMedida())
								.getDescripcionCabecera());
				List<CronogramaCostoActividad> listCronogramaCostoActividad=cronogramaCostoActividadService
				.findCronogramaCostoActividadByCostoActividadID(costoActividad
						.getCostoActividadID());
				List<CronogramaCostoActividad> listCronogramaCostoActividadTemp= new ArrayList<CronogramaCostoActividad>();
				for (CronogramaCostoActividad cronogramaCostoActividad : listCronogramaCostoActividad) {
					if(cronogramaCostoActividad.getCantidad()>0){
						listCronogramaCostoActividadTemp.add(cronogramaCostoActividad);
					}
				}
				costoActividad.setListCronogramaCostoActividad((List<CronogramaCostoActividad>) UtilList.orderAscList(listCronogramaCostoActividadTemp,"periodo"));
			}
		}

		return listCostoActividad;
	}

	@SuppressWarnings("unchecked")
	private List<MetaPorActividad> llenaMetaPorActividad(
			List<MetaPorActividad> listMetaPorActividad) {

		if (listMetaPorActividad != null) {
			for (MetaPorActividad metaPorActividad : listMetaPorActividad) {
				metaPorActividad
						.setDescripcionTipoIndicadorActividad(tablaEspecificaService
								.findTablaEspecificaById(
										metaPorActividad
												.getFkIdtablaespTipoIndicadorActividad())
								.getDescripcionCabecera());
				metaPorActividad
						.setDescripcionUnidadMedida(tablaEspecificaService
								.findTablaEspecificaById(
										metaPorActividad
												.getFkIdtablaespUnidadMedida())
								.getDescripcionCabecera());
				List<CronogramaMetaPorActividad> listCronogramaMetaPorActividad = cronogramaMetaPorActividadService
				.findCronogramaMetaPorActividadXMetaPorActividadId(metaPorActividad
						.getMetaPorActividadID());
				List<CronogramaMetaPorActividad> listCronogramaMetaPorActividadTemp = new ArrayList<CronogramaMetaPorActividad>();
				for (CronogramaMetaPorActividad cronogramaMetaPorActividad : listCronogramaMetaPorActividad) {
					if(cronogramaMetaPorActividad.getCantidadMetaActividadProgPorPeriodo()>0){
						listCronogramaMetaPorActividadTemp.add(cronogramaMetaPorActividad);
					}
				}
				metaPorActividad
						.setListCronogramaMetaPorActividad((List<CronogramaMetaPorActividad>) UtilList.orderAscList(listCronogramaMetaPorActividadTemp,"periodo"));
			}
		}
		return listMetaPorActividad;
	}
}
